import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;

public class AESUtil {
    private static final String AES_ALGORITHM = "AES/CBC/PKCS5Padding";
    private static final String SECRET_KEY; // 16字节密钥
    private static final String INIT_VECTOR; // 16字节初始化向量

    static {
        try {
            SECRET_KEY = AESKeyGenerator.generateAESKey(128);
            INIT_VECTOR = generateInitVector();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    public static String encrypt(String data) {
        try {
            byte[] ivBytes = Base64.getDecoder().decode(INIT_VECTOR);
            IvParameterSpec iv = new IvParameterSpec(ivBytes);
            SecretKeySpec secretKey = new SecretKeySpec(Base64.getDecoder().decode(SECRET_KEY), "AES");

            Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);

            byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
            return Base64.getEncoder().encodeToString(encryptedBytes);
        } catch (Exception e) {
            System.err.println("加密失败: " + e.getMessage());
            return data;
        }
    }

    public static String decrypt(String encryptedData) {
        try {
            byte[] ivBytes = Base64.getDecoder().decode(INIT_VECTOR);
            IvParameterSpec iv = new IvParameterSpec(ivBytes);
            SecretKeySpec secretKey = new SecretKeySpec(Base64.getDecoder().decode(SECRET_KEY), "AES");

            Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);

            byte[] decodedBytes = Base64.getDecoder().decode(encryptedData);
            byte[] decryptedBytes = cipher.doFinal(decodedBytes);
            return new String(decryptedBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            System.err.println("解密失败: " + e.getMessage());
            return encryptedData;
        }
    }

    public static class AESKeyGenerator {

        /**
         * 生成一个AES密钥
         *
         * @param keySize 密钥大小，可以是128、192或256位
         * @return 返回一个Base64编码的密钥字符串
         * @throws NoSuchAlgorithmException 如果密钥大小不被支持
         */
        public static String generateAESKey(int keySize) throws NoSuchAlgorithmException {
            // 创建一个KeyGenerator对象，用于生成AES密钥
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            // 初始化KeyGenerator对象，指定密钥大小
            keyGenerator.init(keySize);
            // 生成密钥
            SecretKey secretKey = (SecretKey) keyGenerator.generateKey();
            // 将密钥转换为字节数组
            byte[] keyBytes = secretKey.getEncoded();
            // 使用Base64编码返回密钥字符串
            return Base64.getEncoder().encodeToString(keyBytes);
        }

        public static void main(String[] args) {
            try {
                // 生成一个128位的AES密钥
                String aesKey = generateAESKey(128);
                System.out.println("Generated AES Key: " + aesKey);
            } catch (NoSuchAlgorithmException e) {
                System.err.println("Error generating AES key: " + e.getMessage());
            }
        }
    }

    private static String generateInitVector() {
        try {
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
            byte[] iv = new byte[16]; // AES要求16字节的IV
            random.nextBytes(iv);
            return Base64.getEncoder().encodeToString(iv);
        } catch (Exception e) {
            throw new RuntimeException("Failed to generate initialization vector", e);
        }
    }
}